//
//  QHHistogramView.swift
//  QHBinimageMan
//
//  Created by Anakin chen on 2021/3/16.
//

import Cocoa

class QHHistogramView: NSView {

    let bottom_h: CGFloat = 20
    
    var ps = [Int](repeating: 0, count: 256)
    var pss = [Int](repeating: 0, count: 16)
    var maxP = 0
    
    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        histogram_draw(dirtyRect)
    }
    
    func addBottom(_ dirtyRect: NSRect) {
        let step = ps.count / pss.count
        let sw = dirtyRect.size.width / CGFloat(pss.count)
        for i in 0..<pss.count {
            let t = NSTextField()
            t.isEditable = false
            t.stringValue = "\((i + 1) * step)"
            t.frame = NSMakeRect(CGFloat(i) * sw, 0, sw, self.bottom_h)
            t.textColor = NSColor(white: 1, alpha: 1)
            t.font = NSFont.systemFont(ofSize: 7)
            t.backgroundColor = NSColor(white: 0, alpha: 1)
            self.addSubview(t)
        }
    }
    
    func reset(pb: CVPixelBuffer) {
        ps = [Int](repeating: 0, count: 256)
        pss = [Int](repeating: 0, count: 16)
        maxP = 0
        
        let w = CVPixelBufferGetBytesPerRow(pb)/4
        let h = CVPixelBufferGetHeight(pb)
        
        let flags = CVPixelBufferLockFlags(rawValue: 0)
        CVPixelBufferLockBaseAddress(pb, flags)
        let pb_data = CVPixelBufferGetBaseAddress(pb)
        let data = unsafeBitCast(pb_data, to: UnsafeMutablePointer<UInt8>.self)
        for y in 0..<h {
            for x in 0..<w {
                let offset = 4 * (y * w + x)
                
                let v = data[offset+1]
                ps[Int(v)] += 1
            }
        }
        CVPixelBufferUnlockBaseAddress(pb, flags)
        
        // 分块
        var i = 0
        for p in ps {
            pss[i/16] += p
            i += 1
        }
        i = 0
        for p in pss {
            pss[i] = p/16
            maxP = max(maxP, pss[i])
            i += 1
        }
    }
    
    private func histogram_draw(_ dirtyRect: NSRect) {
        guard let ctx = NSGraphicsContext.current?.cgContext else {
            return
        }
        if maxP == 0 {
            return
        }
        let path = CGMutablePath()
        path.move(to: CGPoint(x: 0, y: self.bottom_h))
        
        let offw = dirtyRect.size.width / CGFloat(pss.count)
        let offh = (dirtyRect.size.height - self.bottom_h) / CGFloat(maxP)
        
        var idx = CGFloat(0)
        for p in pss {
            path.addLine(to: CGPoint(x: idx * offw, y: CGFloat(p) * offh + self.bottom_h))
            idx += CGFloat(1)
            path.addLine(to: CGPoint(x: idx * offw, y: CGFloat(p) * offh + self.bottom_h))
            path.addLine(to: CGPoint(x: idx * offw, y: self.bottom_h))
        }
        
        ctx.addPath(path)
        
        ctx.setFillColor(red: 123, green: 123, blue: 123, alpha: 1)
        ctx.drawPath(using: .fill)
    }
    
}
